home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / vm / vmInt.h < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  24.7 KB  |  643 lines

  1. /*
  2.  * vmInt.h --
  3.  *
  4.  *    Machine independent virtual memory data structures and procedure
  5.  *    headers used internally by the virtual memory module.
  6.  *
  7.  * Copyright (C) 1985 Regents of the University of California
  8.  * All rights reserved.
  9.  *
  10.  *
  11.  * $Header: /cdrom/src/kernel/Cvsroot/kernel/vm/vmInt.h,v 9.13 91/09/10 18:29:22 rab Exp $ SPRITE (Berkeley)
  12.  */
  13.  
  14. #ifndef _VMINT
  15. #define _VMINT
  16.  
  17. #ifdef KERNEL
  18. #include <vmMach.h>
  19. #include <fs.h>
  20. #include <list.h>
  21. #include <sync.h>
  22. #include <proc.h>
  23. #include <status.h>
  24. #else
  25. #include <kernel/vmMach.h>
  26. #include <kernel/fs.h>
  27. #include <kernel/sync.h>
  28. #include <kernel/proc.h>
  29. #include <status.h>
  30. #include <list.h>
  31. #endif
  32.  
  33. /*
  34.  * KERNEL VIRTUAL ADDRESS SPACE
  35.  *
  36.  * The kernel's virtual address space is divided up in the following way:
  37.  *
  38.  * -------------------------------------- mach_KernStart
  39.  * |                    |
  40.  * | Machine dependent stuff        |
  41.  * |                    |
  42.  * -------------------------------------- mach_StackBottom
  43.  * |                    |
  44.  * | Stack for the main process which    |
  45.  * | is mach_KernStackSize bytes long.    |
  46.  * |                    |
  47.  * -------------------------------------- mach_CodeStart
  48.  * |                    |
  49.  * | Kernel code + data.  Current end    |
  50.  * | is vmMemEnd which is incremented    |
  51.  * | each time Vm_RawAlloc is called.    |
  52.  * | The absolute end is        |
  53.  * | mach_CodeStart + vmKernMemSize.    |            
  54.  * |                    |
  55.  * -------------------------------------- mach_CodeStart + vmKernMemSize
  56.  * |                    |
  57.  * | Kernel stacks.  There are        |
  58.  * | vmMaxProcesses worth of stacks.    |
  59.  * |                    |
  60.  * -------------------------------------- vmStackEndAddr and vmMapBaseAddr
  61.  * |                    |
  62.  * | Place to map pages into the    |
  63.  * | kernel's VAS.  There are at most    |
  64.  * | vmNumMappedPages mapped at once.    |
  65.  * |                    |
  66.  * -------------------------------------- vmMapEndAddr
  67.  * |                    |
  68.  * | Machine dependent part of VAS    |
  69.  * |                    |
  70.  * -------------------------------------- vmBlockCacheBaseAddr
  71.  * |                    |
  72.  * | File system block cache pages.    |
  73.  * |                    |
  74.  * -------------------------------------- vmBlockCacheEndAddr and mach_KernEnd
  75.  *
  76.  *
  77.  * USER VIRTUAL ADDRESS SPACE
  78.  *
  79.  * A users virtual address space is divided into three segments:
  80.  * code, heap and stack.  The code is in the lowest part of the
  81.  * VAS and is followed by the heap segment which grows towards the stack.
  82.  * The stack is at the top of the virtual address and grows towards the
  83.  * heap.  The two fields offset and numPages in each segment table entry
  84.  * define the bounds of a segment.  offset is the virtual page number that
  85.  * maps to page table entry zero.  Thus the index into the page table for any
  86.  * page is the page number minus the offset.  The offset for the code and
  87.  * heap segment is fixed and the offset for the stack segment will change
  88.  * as the page table grows.  numPages is the number of pages that can be
  89.  * accessed for a segment.  Thus for code and heap segments, offset is the
  90.  * lowest accessible page and (numPages + offset - 1) is the highest
  91.  * accessible page.  For a stack segment the highest accessible page is fixed
  92.  * at mach_LastUserStackPage and the lowest accessible page is
  93.  * (mach_LastUserStackPage - numPages + 1).
  94.  *
  95.  * The heap and stack grow in chunks that contain a multiple of
  96.  * vmPageTableInc pages.  Thus the page table may contain more page table
  97.  * entries then there are valid pages for a segment.  Two heap and stack
  98.  * segments overlap if the page tables overlap.
  99.  *
  100.  * -------------------------------------- codeSeg.offset * vm_PageSize
  101.  * |                    |
  102.  * | Code for the process.  There are    |
  103.  * | codeSeg.numPages worth of pages    |
  104.  * | in the segment.            |
  105.  * |                    |
  106.  * -------------------------------------- heapSeg.offset * vm_PageSize
  107.  * |                    |
  108.  * | Heap for the process.  There are    |
  109.  * | heapSeg.numPages worth of virtual     |
  110.  * | pages in the segment.  However, The|
  111.  * | actual end corresponds to the size |<- Last addr in heap segment =
  112.  * | of the page table.            |   (heapSeg.offset + heapSeg.numPages)
  113.  * |                    |                * vm_PageSize
  114.  * |                    |
  115.  * -------------------------------------- (heapSeg.offset + heapSeg.ptSize) *
  116.  *            |                           vm_PageSize
  117.  *            V            
  118.  *
  119.  *            A
  120.  *            |
  121.  * -------------------------------------- stackSeg.offset * vm_PageSize
  122.  * |                    |
  123.  * | Stack for the process.  There are    |
  124.  * | stackSeg.numPages worth of virtual |<- First addr in stack segment =
  125.  * | pages for the segment.  However,   |   (mach_LastUserStackPage -
  126.  * | like the heap segment the actual    |    stackSeg.numPages + 1) *
  127.  * | size corresponds to the size of the|    vm_PageSize
  128.  * | page table.            |
  129.  * |                    |
  130.  * -------------------------------------- mach_MaxUserStackAddr
  131.  *
  132.  * SYNCHRONIZATION
  133.  *
  134.  * There are four types of synchronization in virtual memory:
  135.  *
  136.  *    1) The monitor lock.
  137.  *    2) Per virtual page lock.
  138.  *    3) Per page table entry lock.
  139.  *    4) Reader and writer locks on a page table.
  140.  *    5) Copy-on-write lock.
  141.  *
  142.  * The monitor lock is used when updating and accessing internal virtual
  143.  * memory structures such as the core map and the segment table.  It is
  144.  * also used to synchronize access to page table entries as will be explained
  145.  * below.
  146.  *
  147.  * Each page managed by VM has a lock count on the page.  As long as the lock
  148.  * count is greater than zero the page will not be stolen from its owner.
  149.  * This is used when a;  page needs to be wired down in memory.
  150.  *
  151.  * Each page table entry has a page-fault-in-progress bit which is set whenever
  152.  * a page is being faulted in.  Whenever this bit is set all other page faults
  153.  * will wait until the fault completes.
  154.  *
  155.  * The page tables have two levels of locking.  First there is a count of
  156.  * the number of users of a page table.  There can be multiple users of
  157.  * the page table at once.  When the user count is greater than zero,
  158.  * the page tables are guaranteed not to be expanded.  Thus while the count
  159.  * is greater than zero a pointer to the page table is guaranteed to be
  160.  * good; that is, noone is going to move the page table.  The second level
  161.  * of locking is an exclusive lock.  When this lock is grabbed there can
  162.  * only be one user of the page table.  This lock cannot be grabbed as long
  163.  * as the user count is greater than zero.  Once this lock is grabbed the
  164.  * page tables can be expanded, moved around or whatever.  The first lock
  165.  * is used when handling page faults or forking segments - operations that
  166.  * require access to the page table outside of the monitor lock.  The
  167.  * second level lock is used when adding or deleting virtual addresses
  168.  * from a segment - operations that require the page table to be reallocated
  169.  * and copied, some of which must be done outside of the monitor lock.
  170.  *
  171.  * The page table locking is only used for heap segments.  Code segments don't
  172.  * need to do the locking because they never expand.  Stack segments don't
  173.  * need it because they can't be shared so the calling process doesn't have to
  174.  * worry about someone else mucking with its page tables.
  175.  *
  176.  * Actual updating of page table entries must be done inside of the monitor.
  177.  * This is because the page allocation code may decide at any time to steal
  178.  * a page from a segment and it does not pay attention to either of the two
  179.  * levels of locking for page tables.  Thus although most parts of a page
  180.  * table entry can be changed at non-monitor level, the resident bit must
  181.  * be examined inside of the monitor.  Also copying and expanding of page
  182.  * tables must also be done inside of the monitor.
  183.  *
  184.  * The last form of synchronization is for copy-on-write.  See the file
  185.  * vmCOW.c for details.
  186.  */
  187.  
  188.  
  189. /*
  190.  * Value returned for a page frame when none are available.
  191.  */
  192. #define VM_NO_MEM_VAL    0x7fffffff
  193.  
  194. extern    int    vmFirstFreePage;    /* The first page frame that is not
  195.                      * owned by the kernel. */
  196. extern    Boolean    vmNoBootAlloc;        /* TRUE implies can no longer use
  197.                      * Vm_BootAlloc. */
  198. extern    Fs_Stream *vmSwapStreamPtr;    /* Swap directory stream. */
  199. extern    int    vmPageShift;        /* Log base 2 of vm_PageSize. */
  200. extern    int    vmPageTableInc;        /* The size in which page tables can
  201.                      * grow. */
  202. extern    int    vmKernMemSize;        /* Amount of code + data available for
  203.                      * the kernel. */
  204. extern    int    vmMaxProcesses;        /* The maximum number of processes that
  205.                      * are supported by virtual memory. */
  206. extern    int    vmNumMappedPages;    /* The maximum number of pages that
  207.                      * can be mapped in by the kernel at
  208.                      * one time. */
  209. extern    Address    vmStackBaseAddr;    /* Base of where kernel stacks are. */
  210. extern    Address    vmStackEndAddr;        /* End of where kernel stacks are. */
  211. extern    Address    vmMapBaseAddr;        /* Base of where to map pages. */
  212. extern    Address    vmMapEndAddr;        /* End of where to map pages. */
  213. extern    int    vmMapBasePage;        /* First page to use for mapping. */
  214. extern    int    vmMapEndPage;        /* Last page to use for mapping. */
  215. extern    Address    vmBlockCacheBaseAddr;    /* Base of the file system cache. */
  216. extern    Address    vmBlockCacheEndAddr;    /* End of the file system cache. */
  217. extern    int    vmMaxMachSegs;        /* Maximum number of machine segments
  218.                      * that the hardware will allow. */
  219. extern    Boolean    vmFreeWhenClean;    /* TRUE if pages should be freed after
  220.                      * they have been cleaned. */
  221. extern    Boolean    vmAlwaysRefuse;        /* TRUE if VM should always refuse the
  222.                      * file systems requests for memory. */
  223. extern    Boolean    vmAlwaysSayYes;        /* TRUE if VM should always satisfy
  224.                      * file system requests for memory. */
  225. extern    int    vmMaxDirtyPages;    /* Maximum number of dirty pages
  226.                      * before waiting for a page to be
  227.                      * cleaned. */
  228. extern    int        vmPagesToCheck;    /* Number of pages to check each time
  229.                      * that the clock is run. */
  230. extern    unsigned int    vmClockSleep;    /* Number of seconds to sleep between
  231.                      * iterations of the clock. */
  232. extern    int        vmMaxPageOutProcs; /* Maximum number of page out procs
  233.                         * at any given time. */
  234. extern    Boolean        vmCORReadOnly;    /* After a cor fault the page is marked
  235.                      * as read only so that it can be
  236.                      * determined if it gets modified. */
  237. extern    Boolean        vmPrefetch;    /* Whether to do prefetch or not. */
  238. extern    Boolean        vmUseFSReadAhead;/* Should have FS do read ahead on
  239.                       * object files. */
  240.  
  241. /*
  242.  * Variables to control negotiations between the file system and the virtual
  243.  * memory system.  Each time that FS asks for a page its reference time is
  244.  * penalized depending on how many pages that it has allocated to it.  The
  245.  * penalty is enforced by subtracting vmCurPenalty seconds from its access time
  246.  * or adding vmCurPenalty to the VM access time.  This is done in the
  247.  * following way.  Let vmPagesPerGroup = total-available-pages /
  248.  * vmNumPageGroups,  vmCurPenalty = 0 and vmBoundary = vmPagesPerGroup.
  249.  * Whenever the number of pages allocated to FS exceeds vmBoundary, vmBoundary
  250.  * is incremented by vmPagesPerGroup and vmCurPenalty is incremented by
  251.  * vmFSPenalty.  Whenever the number of pages allocated to FS goes under
  252.  * vmBoundary, vmBoundary is decremented by vmPagesPerGroup and vmCurPenalty is
  253.  * decremented by vmFSPenalty.
  254.  */
  255. extern    int    vmFSPenalty;    /* Number of seconds FS is penalized when it
  256.                  * asks for page. */
  257. extern    int    vmNumPageGroups;/* The number of groups to divide memory up
  258.                  * into. */
  259. extern    int    vmPagesPerGroup;/* The number of pages in each group. */
  260. extern    int    vmCurPenalty;    /* The number of seconds that FS is currently
  261.                  * penalized by. */
  262. extern    int    vmBoundary;    /* The current number of pages that must be
  263.                  * exceeded or gone under before changing the
  264.                  * penalty. */
  265.  
  266. /*
  267.  * Variables to control use of modify and reference bits.
  268.  */
  269. extern    Boolean    vmWriteablePageout;    /* Page out all pages that are
  270.                      * writeable before recycling them
  271.                      * whether they have been modified
  272.                      * or not. */
  273. extern    Boolean    vmWriteableRefPageout;    /* Page out all pages that have been
  274.                      * referenced and are writeable
  275.                      * before recycling them whether they
  276.                      * have been modified or not. */
  277.  
  278. /*
  279.  * Flags for VmPageAllocate and VmPageAllocateInt:
  280.  *
  281.  *  VM_CAN_BLOCK    Can block if no clean memory is available.
  282.  *  VM_ABORT_WHEN_DIRTY    Abrot even if VM_CAN_BLOCK is set if have exceeded
  283.  *            the maximum number of dirty pages on the dirty list.
  284.  */
  285. #define    VM_CAN_BLOCK        0x1
  286. #define    VM_ABORT_WHEN_DIRTY    0x2
  287.  
  288.  
  289. /*---------------------------------------------------------------------------*/
  290.  
  291. /*
  292.  *                     Segment Table Structure
  293.  *
  294.  * There is one segment table for the entire system that contains
  295.  * one entry for each segment. Associated with each segment table entry
  296.  * is a reference count of processes that are using the segment.  If
  297.  * the reference count is non-zero then the segment is actively being used.
  298.  * If the reference count is zero then the segment table entry is either in the
  299.  * inactive segment list or the free segment list.  The inactive segment list
  300.  * is a list of segment table entries that are not currently in use by
  301.  * any process but contain code segments that can be reused if a new process
  302.  * needs the code segment.  The free segment list is a list of segment
  303.  * table entries that are not being used by any process and do not contain code
  304.  * segments that could be used by future processes.
  305.  *
  306.  * All processes that are sharing segments are linked together.  This is
  307.  * done by having each segment table entry contain a pointer to a list of
  308.  * pointers to proc table entries.
  309.  *
  310.  * See vmSeg.c for the actual use of the segment table and the free and
  311.  * inactive lists.
  312.  */
  313.  
  314. /*
  315.  * An element of a linked list of processes sharing a segment.  Each
  316.  * element of the linked list points to the proc table entry of the process
  317.  * that is sharing the segment.
  318.  */
  319. typedef struct {
  320.     List_Links    links;
  321.     Proc_ControlBlock    *procPtr;
  322. } VmProcLink;
  323.  
  324. /*
  325.  * Memory space that has to be allocated for each segment.
  326.  */
  327. typedef    struct {
  328.     Boolean        spaceToFree;    /* TRUE if this structure contains
  329.                        space that has to be deallocated.*/
  330.     Vm_PTE        *ptPtr;        /* Pointer to page table */
  331.     int            ptSize;        /* Size of page table. */
  332.     VmProcLink        *procLinkPtr;    /* Pointer to proc list element. */
  333. } VmSpace;
  334.  
  335. /*
  336.  * VmSegmentDeleteInt returns different status values depending on the
  337.  * reference count and segment type.  These status values indicate what
  338.  * should be done with the segment after the procedure returns.
  339.  *
  340.  *    VM_DELETE_SEG -        The segment should be deleted.
  341.  *    VM_CLOSE_OBJ_FILE -    Don't delete the segment, but close the file
  342.  *                containing the code for the segment.
  343.  *    VM_DELETE_NOTHING -    Don't do anything.
  344.  */
  345. typedef enum {
  346.     VM_DELETE_SEG,
  347.     VM_CLOSE_OBJ_FILE,
  348.     VM_DELETE_NOTHING,
  349. } VmDeleteStatus;
  350.  
  351. /*
  352.  * System segment number.
  353.  */
  354. #define VM_SYSTEM_SEGMENT       0
  355.  
  356. /*
  357.  * Segment table flags:
  358.  *
  359.  *   VM_SEG_FREE        The segment is currently on the free list.
  360.  *   VM_SEG_INACTIVE        The segment is currently on the inactive
  361.  *                list.
  362.  *   VM_SWAP_FILE_OPENED    A swap file has been opened for this segment.
  363.  *   VM_SWAP_FILE_LOCKED    The swap file for this segment is being
  364.  *                opened or written to.
  365.  *   VM_SEG_DEAD        This segment is in the process of being
  366.  *                deleted.
  367.  *   VM_PT_EXCL_ACC        Someone has grabbed exclusive access to the
  368.  *                the page tables.
  369.  *   VM_DEBUGGED_SEG        This is a special code segment that is being
  370.  *                written by the debugger.
  371.  *   VM_SEG_CANT_COW        This segment cannot be forked copy-on-write.
  372.  *   VM_SEG_COW_IN_PROGRESS    This segment is being actively copied at
  373.  *                fork time.
  374.  *   VM_SEG_IO_ERROR        An I/O error has occurred while paging to
  375.  *                or from this segment.
  376.  */
  377.  
  378. #define    VM_SEG_FREE            0x001
  379. #define    VM_SEG_INACTIVE            0x002
  380. #define    VM_SWAP_FILE_OPENED        0x004
  381. #define    VM_SWAP_FILE_LOCKED        0x008
  382. #define    VM_SEG_DEAD            0x010
  383. #define    VM_PT_EXCL_ACC            0x020
  384. #define    VM_DEBUGGED_SEG            0x040
  385. /* 0x080 is not used */
  386. #define    VM_SEG_CANT_COW            0x100
  387. #define    VM_SEG_COW_IN_PROGRESS        0x200
  388. #define VM_SEG_IO_ERROR                0x400
  389.  
  390.  
  391. /*---------------------------------------------------------------------------*/
  392.  
  393. /*
  394.  *             Core map structure.
  395.  *
  396.  * The core map contains one entry for each page in physical memory.
  397.  * There are four lists that run through the core map: the allocate list,
  398.  * the dirty list, the free list and the reserve list.  All pages that aren't
  399.  * be used by any segment are on the free list.  All pages that are being
  400.  * used by users processes are on the allocate list or the dirty list.
  401.  * The allocate list is used to keep track of which pages are the best
  402.  * candidates to use when a new page is needed.  All pages that are not
  403.  * attached to any segment are at the front of the allocate list and the
  404.  * rest of the pages on the allocate list are kept in LRU order.  The dirty
  405.  * list is a list of pages that are being written to disk.  The reserve
  406.  * list is a list of pages that are kept in case the kernel needs memory
  407.  * and no clean pages are available.
  408.  *
  409.  * See vmPage.c for the actual use of the core map and the lists.
  410.  * allocate lists.
  411.  */
  412.  
  413. typedef struct VmCore {
  414.     List_Links    links;        /* Links for allocate, free, dirty and reserver
  415.                  * lists */
  416.     Vm_VirtAddr    virtPage;    /* The virtual page information for this page */
  417.     int        wireCount;    /* The number of times that the page has bee
  418.                  * wired down by users. */
  419.     int        lockCount;    /* The number of times that this page has been
  420.                    locked down (i.e. made unpageable). */
  421.     int     flags;        /* Flags that indicate the state of the page
  422.                    as defined below. */
  423.     int        lastRef;    /* Time in seconds that pages reference bit
  424.                  * last cleared by clock. */
  425. } VmCore;
  426.  
  427. /*
  428.  * The following defines the state of the page:
  429.  *
  430.  * VM_FREE_PAGE            The page is not attached to any segment.
  431.  * VM_DIRTY_PAGE           The page is on the dirty list.
  432.  * VM_SEG_PAGEOUT_WAIT        A segment is waiting for this page to be
  433.  *                cleaned.
  434.  * VM_PAGE_BEING_CLEANED    The page is actually being cleaned.
  435.  * VM_DONT_FREE_UNTIL_CLEAN    This page cannot be freed until it has
  436.  *                been written out.
  437.  */
  438. #define VM_FREE_PAGE             0x01
  439. #define VM_DIRTY_PAGE             0x02
  440. #define VM_SEG_PAGEOUT_WAIT         0x04
  441. #define VM_PAGE_BEING_CLEANED        0x08
  442. #define    VM_DONT_FREE_UNTIL_CLEAN    0x10
  443.  
  444. /*
  445.  * Copy-on-write info struct.
  446.  */
  447. typedef struct VmCOWInfo {
  448.     List_Links        cowList;
  449.     int            numSegs;
  450.     Sync_Condition    condition;
  451.     Boolean        copyInProgress;
  452. } VmCOWInfo;
  453.  
  454. /*
  455.  * Shared memory.
  456.  */
  457. extern int vmShmDebug;
  458. /*
  459.  * Debugging printf.
  460.  */
  461. #ifdef lint
  462. #define dprintf printf
  463. #else
  464. #define dprintf if (vmShmDebug & 2) printf
  465. #endif
  466.  
  467. /*
  468.  * Macros to get a pointer to a page table entry.
  469.  */
  470. #ifdef CLEAN2
  471. #define    VmGetPTEPtr(segPtr, page) \
  472.     (&((segPtr)->ptPtr[(page) - (segPtr)->offset]))
  473. #else /* CLEAN */
  474. #define    VmGetPTEPtr(segPtr, page) \
  475.     (((((page) - (segPtr)->offset) > (segPtr)->ptSize)) ? \
  476.     panic("Page number outside bounds of page table\n"), (Vm_PTE *) NIL : \
  477.     (&((segPtr)->ptPtr[(page) - (segPtr)->offset])))
  478. #endif /* CLEAN */
  479.  
  480. #ifdef CLEAN
  481. #define    VmGetAddrPTEPtr(virtAddrPtr, page) \
  482.     (&((virtAddrPtr)->segPtr->ptPtr[(page) - segOffset(virtAddrPtr)]))
  483. #else /* CLEAN */
  484. #define    VmGetAddrPTEPtr(virtAddrPtr, page) \
  485.     (((((page) - segOffset(virtAddrPtr)) < 0) || \
  486.     (((page) - segOffset(virtAddrPtr)) > (virtAddrPtr)->segPtr->ptSize) ) ? \
  487.     panic("Page number outside bounds of page table\n"), (Vm_PTE *) NIL : \
  488.     (&((virtAddrPtr)->segPtr->ptPtr[(page) - segOffset(virtAddrPtr)])))
  489. #endif /* CLEAN */
  490.  
  491. /*
  492.  * Macro to increment a page table pointer.
  493.  */
  494. #define    VmIncPTEPtr(ptePtr, val) ((ptePtr) += val)
  495.  
  496. /*
  497.  * Macro to get a virtAddr's offset in the page table.
  498.  */
  499. #define segOffset(virtAddrPtr) (( (virtAddrPtr)->sharedPtr== \
  500.     (Vm_SegProcList *)NIL) ? (virtAddrPtr)->segPtr->offset :\
  501.        (virtAddrPtr)->sharedPtr->offset)
  502.  
  503. /*----------------------------------------------------------------------------*/
  504.  
  505. #define min(a,b) ((a)<(b)?(a):(b))
  506. #define max(a,b) ((a)>(b)?(a):(b))
  507.  
  508. /*
  509.  * Initialization routines.
  510.  */
  511. extern void VmSegTableAlloc _ARGS_((void));
  512. extern void VmSegTableInit _ARGS_((void));
  513. extern void VmStackInit _ARGS_((void));
  514. extern void VmCoreMapAlloc _ARGS_((void));
  515. extern void VmCoreMapInit _ARGS_((void));
  516. /*
  517.  * Page allocation routines.
  518.  */
  519. extern    unsigned int    VmPageAllocate _ARGS_((Vm_VirtAddr *virtAddrPtr,
  520.         int flags));
  521. extern    unsigned int    VmPageAllocateInt _ARGS_((Vm_VirtAddr *virtAddrPtr,
  522.         int flags));
  523. extern    unsigned int    VmGetReservePage _ARGS_((Vm_VirtAddr *virtAddrPtr));
  524. /*
  525.  * Routine to free pags.
  526.  */
  527. extern void VmPageFree _ARGS_((unsigned int pfNum));
  528. extern void VmPageFreeInt _ARGS_((unsigned int pfNum));
  529. /*
  530.  * Routines to put pages on lists.
  531.  */
  532. extern void VmPutOnFreeSegList _ARGS_((register Vm_Segment *segPtr));
  533. extern void VmPutOnFreePageList _ARGS_((unsigned int pfNum));
  534. /*
  535.  * Routines to lock pages.
  536.  */
  537. extern void VmLockPageInt _ARGS_((unsigned int pfNum));
  538. extern void VmUnlockPage _ARGS_((unsigned int pfNum));
  539. extern void VmUnlockPageInt _ARGS_((unsigned int pfNum));
  540. /*
  541.  * Routine to see if a page is pinned down.
  542.  */
  543. extern Boolean VmPagePinned _ARGS_((Vm_PTE *ptePtr));
  544. /*
  545.  * Routine to handle page faults.
  546.  */
  547. extern void VmVirtAddrParse _ARGS_((Proc_ControlBlock *procPtr,
  548.     Address virtAddr, register Vm_VirtAddr *transVirtAddrPtr));
  549. extern Boolean VmCheckBounds _ARGS_((register Vm_VirtAddr *virtAddrPtr));
  550. extern void VmZeroPage _ARGS_((unsigned int pfNum));
  551. extern void VmKillSharers _ARGS_((register Vm_Segment *segPtr));
  552. extern void VmSwapFileRemove _ARGS_((Fs_Stream *swapStreamPtr,
  553.     char *swapFileName));
  554. extern ReturnStatus VmPageFlush _ARGS_((Vm_VirtAddr *virtAddrPtr,
  555.     int length, Boolean toDisk, Boolean wantRes));
  556. extern int VmCountDirtyPages _ARGS_((void));
  557.  
  558. /*
  559.  * Segment handling routines.
  560.  */
  561. extern ReturnStatus VmAddToSeg _ARGS_((register Vm_Segment *segPtr,
  562.     int firstPage, int lastPage));
  563. extern VmDeleteStatus VmSegmentDeleteInt _ARGS_((register Vm_Segment *segPtr,
  564.     register Proc_ControlBlock *procPtr, VmProcLink **procLinkPtrPtr,
  565.     Fs_Stream **objStreamPtrPtr, Boolean migFlag));
  566. extern void VmDecPTUserCount _ARGS_((register Vm_Segment *segPtr));
  567. extern    Vm_Segment    *VmGetSegPtr _ARGS_((int segNum));
  568. extern void VmFlushSegment _ARGS_((Vm_VirtAddr *virtAddrPtr, int lastPage));
  569. extern Vm_SegProcList *VmFindSharedSegment _ARGS_((List_Links *sharedSegs,
  570.     Address virtAddr));
  571. extern Boolean VmCheckSharedSegment _ARGS_((Proc_ControlBlock *procPtr,
  572.     Vm_Segment *segPtr));
  573. extern void VmPrintSharedSegs _ARGS_((Proc_ControlBlock *procPtr));
  574.  
  575. /*
  576.  * Routines to validate and invalidate pages.
  577.  */
  578. extern void VmPageValidate _ARGS_((Vm_VirtAddr *virtAddrPtr));
  579. extern void VmPageValidateInt _ARGS_((Vm_VirtAddr *virtAddrPtr,
  580.     register Vm_PTE *ptePtr));
  581. extern void VmPageInvalidate _ARGS_((register Vm_VirtAddr *virtAddrPtr));
  582. extern void VmPageInvalidateInt _ARGS_((Vm_VirtAddr *virtAddrPtr,
  583.     register Vm_PTE *ptePtr));
  584. extern void VmValidatePagesInt _ARGS_((Vm_Segment *segPtr, int firstPage,
  585.     int lastPage, Boolean zeroFill, Boolean clobber));
  586. /*
  587.  * VM list routines.  Like normal list routines but do more sanity checks.
  588.  */
  589. extern void VmListMove _ARGS_((register List_Links *itemPtr,
  590.     register List_Links *destPtr));
  591. extern void VmListRemove _ARGS_((register List_Links *itemPtr));
  592. extern void VmListInsert _ARGS_((register List_Links *itemPtr,
  593.     register List_Links *destPtr));
  594. /*
  595.  * Routines for copy-on-write and copy-on-reference.
  596.  */
  597. extern Boolean VmSegCanCOW _ARGS_((Vm_Segment *segPtr));
  598. extern void VmSegCantCOW _ARGS_((Vm_Segment *segPtr));
  599. extern void VmSegCOWDone _ARGS_((Vm_Segment *segPtr, Boolean cantCOW));
  600. extern void VmSegFork _ARGS_((Vm_Segment *srcSegPtr, Vm_Segment *destSegPtr));
  601. extern void VmCOWDeleteFromSeg _ARGS_((register Vm_Segment *segPtr,
  602.     register int firstPage, register int lastPage));
  603. extern ReturnStatus VmCOR _ARGS_((register Vm_VirtAddr *virtAddrPtr));
  604. extern void VmCOW _ARGS_((register Vm_VirtAddr *virtAddrPtr));
  605. extern void VmPageSwitch _ARGS_((unsigned int pageNum, Vm_Segment *newSegPtr));
  606. extern ReturnStatus VmCOWCopySeg _ARGS_((register Vm_Segment *segPtr));
  607. /*
  608.  * Procedures for remote page access.
  609.  */
  610. extern ReturnStatus VmCopySwapSpace _ARGS_((register Vm_Segment *srcSegPtr,
  611.     register Vm_Segment *destSegPtr));
  612. extern ReturnStatus VmPageServerRead _ARGS_((Vm_VirtAddr *virtAddrPtr,
  613.     unsigned int pageFrame));
  614. extern ReturnStatus VmPageServerWrite _ARGS_((Vm_VirtAddr *virtAddrPtr,
  615.     unsigned int pageFrame, Boolean toDisk));
  616. extern ReturnStatus VmFileServerRead _ARGS_((Vm_VirtAddr *virtAddrPtr,
  617.     unsigned int pageFrame));
  618. extern void VmMakeSwapName _ARGS_((int segNum, char *fileName));
  619. extern ReturnStatus VmOpenSwapFile _ARGS_((register Vm_Segment *segPtr));
  620. extern ReturnStatus VmCopySwapPage _ARGS_((register Vm_Segment *srcSegPtr,
  621.     int virtPage, register Vm_Segment *destSegPtr));
  622. extern void VmSwapFileLock _ARGS_((register Vm_Segment *segPtr));
  623. extern void VmSwapFileUnlock _ARGS_((register Vm_Segment *segPtr));
  624. /*
  625.  * Procedures for process migration.
  626.  */
  627. extern void VmPutOnDirtyList _ARGS_((unsigned int pfNum));
  628. /*
  629.  * Procedures for mapping.
  630.  */
  631. extern Address VmMapPage _ARGS_((unsigned int pfNum));
  632. extern void VmUnmapPage _ARGS_((Address mappedAddr));
  633. extern void VmRemapPage _ARGS_((Address addr, unsigned int pfNum));
  634. extern ReturnStatus Vm_MmapInt _ARGS_((Address startAddr, int length, int prot,
  635.     int share, int streamID, int fileAddr, Address *mappedAddr));
  636. /*
  637.  * Prefetch routine.
  638.  */
  639. extern void VmPrefetch _ARGS_((register Vm_VirtAddr *virtAddrPtr,
  640.     register Vm_PTE *ptePtr));
  641.  
  642. #endif /* _VMINT */
  643.